package com.mkh.st.common.data.datascope;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.PageUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mkh.st.common.core.util.BasePage;
import com.mkh.st.common.security.util.SecurityUtils;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * 数据访问层工具类
 *
 * @Author: pc
 * @CreateDate: 2021/7/20 15:18
 */
public class DaoUtil {

	/**
	 * 分页查询
	 *
	 * @param source
	 * @param basePage
	 * @return
	 */
	public static <T> Page<T> page(List<T> source, BasePage basePage) {
		Page<T> page = new Page<>();
		if (CollectionUtil.isEmpty(source)) {
			return page;
		}
		page.setTotal(source.size());
		page.setCurrent(basePage.getCurrent());
		page.setSize(basePage.getSize());
		page.setPages(PageUtil.totalPage((int) page.getTotal(), (int) page.getSize()));
		//计算索引
		int fromIndex = (int) ((page.getCurrent() - 1) * page.getSize());
		int toIndex = (int) (fromIndex + page.getSize());
		if (toIndex > source.size()) {
			toIndex = source.size();
		}
		page.setRecords(source.subList(fromIndex, toIndex));
		return page;
	}


	/**
	 * 转化page
	 *
	 * @param source
	 * @param clazz
	 * @param <T>
	 * @return
	 */
	public static <T> Page<T> convertPage(IPage<?> source, Class<T> clazz) {
		Page<T> page = new Page<>();
		//页元数据
		BeanUtil.copyProperties(source, page);
		List<?> records = source.getRecords();
		if (CollectionUtil.isNotEmpty(records)) {
			//页主数据
			List<T> data = new ArrayList<>();
			try {
				for (Object record : records) {
					T obj = clazz.newInstance();
					BeanUtil.copyProperties(record, obj);
					data.add(obj);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			page.setRecords(data);
		}
		return page;
	}

	/**
	 * 逻辑删包装类
	 *
	 * @param clazz
	 * @param id
	 * @param <T>
	 * @return
	 */
	public static <T> UpdateWrapper<T> getLogicDelWrappers(Class<T> clazz, Long id) {
		UpdateWrapper<T> update = Wrappers.update();
		update.eq("id", id).set("deleted", 1);
		return update;
	}

	/**
	 * 获取逻辑删实体对象
	 *
	 * @param clazz
	 * @param id
	 * @param <T>
	 * @return
	 */
	public static <T> T getLogicDelEntity(Class<T> clazz, Long id) {
		T t = null;
		try {
			t = clazz.newInstance();
			//设置id
			setDeclaredField(t, "id", id);
			//设置deleted
			setDeclaredField(t, "deleted", 1);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return t;
	}

	/**
	 * 填充公共字段数据
	 *
	 * @param obj
	 * @param tenantId
	 * @param createBy
	 * @param updateBy
	 */
	public static void fillFields(Object obj, boolean tenantId, boolean createBy, boolean updateBy) {
		if (SecurityUtils.getUser() == null) {
			return;
		}
		if (tenantId) {
			//设置租户ID
			setDeclaredField(obj, "tenantId", Long.valueOf(SecurityUtils.getUser().getTenantId()));
		}
		if (createBy) {
			//设置创建人
			setDeclaredField(obj, "createBy", SecurityUtils.getUser().getUsername());
		}
		if (updateBy) {
			//设置修改人
			setDeclaredField(obj, "updateBy", SecurityUtils.getUser().getUsername());
		}
	}

	/**
	 * 租户、创建人信息
	 *
	 * @param obj
	 */
	public static void fillCommonFields(Object obj) {
		fillFields(obj, true, true, true);
	}

	/**
	 * 修改人信息
	 *
	 * @param obj
	 */
	public static void fillUpdateBy(Object obj) {
		fillFields(obj, false, false, true);
	}

	/**
	 * 设置属性值
	 *
	 * @param obj
	 * @param fieldName
	 * @param value
	 */
	private static void setDeclaredField(Object obj, String fieldName, Object value) {
		try {
			Field updateByField = obj.getClass().getDeclaredField(fieldName);
			updateByField.setAccessible(true);
			updateByField.set(obj, value);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
